#include "uniMesh.hpp"

namespace hms {


UniMesh::UniMesh(
	Array2i size,
	Array2s diff,
	Vector2s origin
) :
	m_size { std::move(size) },
	m_diff { std::move(diff) },
	m_origin { std::move(origin) }
{
	if ( m_diff.isApprox( Array2s{0,0}, epsilon) )
		throw std::runtime_error( "Distance between cells must not be zero!" );

	m_cells.storeData();
	m_edges.storeIndices();
}

UniMesh::UniMesh(
	Index nCellsX,
	Index nCellsY,
	scalar dx,
	scalar dy,
	Vector2s origin
) :
	UniMesh( {nCellsX, nCellsY}, {dx, dy}, std::move(origin) )
{}


auto UniMesh::dx    () const -> scalar { return m_diff.x(); }
auto UniMesh::dy    () const -> scalar { return m_diff.y(); }
auto UniMesh::diff  () const -> const Array2s& { return m_diff; }

auto UniMesh::origin() const -> const Vector2s& { return m_origin; }

auto UniMesh::nCellsXImp() const -> Index { return m_size.x(); }
auto UniMesh::nCellsYImp() const -> Index { return m_size.y(); }

auto UniMesh::sizeImp() const -> SizeType { return m_size; }

auto UniMesh::vertexImp(Index i) const -> Vector2s {
	return m_origin + Vector2s{
		( i % (nCellsX()+1) )*dx(),
		( i / (nCellsX()+1) )*dy()
	};
}


auto UniMesh::domainAreaImp() const -> scalar {
	return nDomainCells()*m_diff.prod();
}



} // end namespace hms